using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using System.IO;

namespace Sensor.UI.ViewModels;

/// <summary>
/// 日志ViewModel，负责日志展示和管理
/// </summary>
public partial class LogViewModel : ViewModelBase
{
    // 日志集合
    public ObservableCollection<LogEntry> LogEntries { get; } = new();

    // 日志显示属性
    [ObservableProperty]
    private bool _autoScroll = true;

    [ObservableProperty]
    private int _maxLogEntries = 1000;

    [ObservableProperty]
    private string _searchText = string.Empty;

    [ObservableProperty]
    private bool _showTimestamp = true;

    [ObservableProperty]
    private bool _showLevel = true;

    // 过滤后的日志集合
    public ObservableCollection<LogEntry> FilteredLogEntries { get; } = new();

    // 日志级别枚举
    public enum LogLevel
    {
        Trace,
        Debug,
        Information,
        Warning,
        Error,
        Critical
    }

    /// <summary>
    /// 日志条目类
    /// </summary>
    public class LogEntry
    {
        public DateTime Timestamp { get; set; }
        public LogLevel Level { get; set; }
        public string Message { get; set; } = string.Empty;
        public string FormattedMessage => ShowTimestamp && ShowLevel 
            ? $"[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] [{Level}] {Message}"
            : ShowTimestamp 
                ? $"[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] {Message}"
                : ShowLevel
                    ? $"[{Level}] {Message}"
                    : Message;

        // 静态属性，用于控制显示格式
        public static bool ShowTimestamp { get; set; } = true;
        public static bool ShowLevel { get; set; } = true;
    }

    public LogViewModel()
    {
        // 初始化时不需要调用SearchTextChanged，因为它会在属性变化时自动调用
    }

    /// <summary>
    /// 添加日志条目
    /// </summary>
    public void AddLogEntry(LogLevel level, string message)
    {
        var entry = new LogEntry
        {
            Timestamp = DateTime.Now,
            Level = level,
            Message = message
        };

        // 在UI线程上添加日志条目
        App.Current.Dispatcher.Invoke(() =>
        {
            LogEntries.Add(entry);

            // 限制日志条目数量
            while (LogEntries.Count > MaxLogEntries)
            {
                LogEntries.RemoveAt(0);
            }

            // 应用过滤
            ApplyFilter();
        });
    }

    /// <summary>
    /// 添加信息日志
    /// </summary>
    public void AddInfo(string message)
    {
        AddLogEntry(LogLevel.Information, message);
    }

    /// <summary>
    /// 添加警告日志
    /// </summary>
    public void AddWarning(string message)
    {
        AddLogEntry(LogLevel.Warning, message);
    }

    /// <summary>
    /// 添加错误日志
    /// </summary>
    public void AddError(string message)
    {
        AddLogEntry(LogLevel.Error, message);
    }

    /// <summary>
    /// 添加调试日志
    /// </summary>
    public void AddDebug(string message)
    {
        AddLogEntry(LogLevel.Debug, message);
    }

    /// <summary>
    /// 清空日志
    /// </summary>
    [RelayCommand]
    private void ClearLogs()
    {
        LogEntries.Clear();
        FilteredLogEntries.Clear();
    }

    /// <summary>
    /// 保存日志到文件
    /// </summary>
    [RelayCommand]
    private async Task SaveLogsToFileAsync()
    {
        try
        {
            var saveFileDialog = new Microsoft.Win32.SaveFileDialog
            {
                Filter = "文本文件 (*.txt)|*.txt|日志文件 (*.log)|*.log|所有文件 (*.*)|*.*",
                DefaultExt = ".log",
                FileName = $"SensorLog_{DateTime.Now:yyyyMMdd_HHmmss}.log"
            };

            if (saveFileDialog.ShowDialog() == true)
            {
                using var writer = new StreamWriter(saveFileDialog.FileName);
                foreach (var entry in LogEntries)
                {
                    await writer.WriteLineAsync(entry.FormattedMessage);
                }

                AddInfo($"日志已保存到: {saveFileDialog.FileName}");
            }
        }
        catch (Exception ex)
        {
            AddError($"保存日志失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 搜索文本变化处理
    /// </summary>
    private void SearchTextChanged(string? value)
    {
        ApplyFilter();
    }

    /// <summary>
    /// 显示时间戳变化处理
    /// </summary>
    private void ShowTimestampChanged(bool value)
    {
        LogEntry.ShowTimestamp = value;
        RefreshLogDisplay();
    }

    /// <summary>
    /// 显示级别变化处理
    /// </summary>
    private void ShowLevelChanged(bool value)
    {
        LogEntry.ShowLevel = value;
        RefreshLogDisplay();
    }

    /// <summary>
    /// 应用过滤条件
    /// </summary>
    private void ApplyFilter()
    {
        App.Current.Dispatcher.Invoke(() =>
        {
            FilteredLogEntries.Clear();

            if (string.IsNullOrWhiteSpace(SearchText))
            {
                foreach (var entry in LogEntries)
                {
                    FilteredLogEntries.Add(entry);
                }
            }
            else
            {
                var searchLower = SearchText.ToLowerInvariant();
                foreach (var entry in LogEntries)
                {
                    if (entry.Message.ToLowerInvariant().Contains(searchLower) ||
                        entry.Level.ToString().ToLowerInvariant().Contains(searchLower))
                    {
                        FilteredLogEntries.Add(entry);
                    }
                }
            }

            // 自动滚动到底部
            if (AutoScroll && FilteredLogEntries.Count > 0)
            {
                // 这里需要绑定到UI控件的滚动行为
                // 在实际实现中，可以通过事件或命令通知UI滚动
            }
        });
    }

    /// <summary>
    /// 刷新日志显示
    /// </summary>
    private void RefreshLogDisplay()
    {
        App.Current.Dispatcher.Invoke(() =>
        {
            // 清空并重新填充过滤后的日志集合
            FilteredLogEntries.Clear();
            foreach (var entry in LogEntries)
            {
                FilteredLogEntries.Add(entry);
            }
        });
    }

    /// <summary>
    /// 处理从串口接收到的消息
    /// </summary>
    public void ProcessSerialMessage(string message)
    {
        // 根据消息内容判断日志级别
        if (message.Contains("错误") || message.Contains("异常") || message.Contains("失败"))
        {
            AddError(message);
        }
        else if (message.Contains("警告") || message.Contains("注意"))
        {
            AddWarning(message);
        }
        else if (message.Contains("调试"))
        {
            AddDebug(message);
        }
        else
        {
            AddInfo(message);
        }
    }

    /// <summary>
    /// 处理异常信息
    /// </summary>
    public void ProcessException(Exception ex)
    {
        AddError($"异常: {ex.Message}");
        if (!string.IsNullOrEmpty(ex.StackTrace))
        {
            AddDebug($"堆栈跟踪: {ex.StackTrace}");
        }
    }
}